import os
import shutil
from pathlib import Path
from typing import Dict, List
from src.config.fileClassifierConfig import FileClassifierConfig

class FileClassifier:
    """
    文件分类器类
    用于将指定目录中的文件按照后缀名分类到不同的子文件夹中
    """
    
    def __init__(self, dataPath: str = None):
        """
        初始化文件分类器
        
        Args:
            dataPath (str): 数据文件夹路径，默认使用配置文件中的路径
        """
        self.dataPath = dataPath or FileClassifierConfig.DEFAULT_DATA_PATH  # 数据文件夹路径
        self.classifiedFolders = {}  # 已分类的文件夹映射
        self.config = FileClassifierConfig  # 配置类引用
        
    def getFilesByExtension(self) -> Dict[str, List[str]]:
        """
        获取data文件夹中所有文件，并按扩展名分组
        
        Returns:
            Dict[str, List[str]]: 以扩展名为key，文件路径列表为value的字典
        """
        filesMap = {}  # 文件扩展名映射
        
        if not os.path.exists(self.dataPath):
            print(f"警告：数据文件夹 {self.dataPath} 不存在")
            return filesMap
            
        for fileName in os.listdir(self.dataPath):
            filePath = os.path.join(self.dataPath, fileName)  # 完整文件路径
            
            # 跳过忽略的文件和文件夹
            if self.config.isIgnoredFile(fileName) or self.config.isIgnoredFolder(fileName):
                continue
            
            # 只处理文件，跳过文件夹
            if os.path.isfile(filePath):
                fileExtension = Path(fileName).suffix.lower()  # 获取文件扩展名并转为小写
                
                # 如果没有扩展名，归类为"其他"
                if not fileExtension:
                    fileExtension = "无扩展名"
                    
                if fileExtension not in filesMap:
                    filesMap[fileExtension] = []
                    
                filesMap[fileExtension].append(filePath)
                
        return filesMap
    
    def createClassifiedFolders(self, filesMap: Dict[str, List[str]]) -> None:
        """
        根据文件扩展名创建分类文件夹
        
        Args:
            filesMap (Dict[str, List[str]]): 文件扩展名映射
        """
        for fileExtension in filesMap.keys():
            # 使用配置文件获取文件夹名称
            if fileExtension == "无扩展名":
                folderName = f"{self.config.CLASSIFIED_FOLDER_PREFIX}{self.config.DEFAULT_UNKNOWN_FOLDER}"
            else:
                folderName = self.config.getFolderNameByExtension(fileExtension)
                
            classifiedPath = os.path.join(self.dataPath, folderName)  # 分类文件夹路径
            
            if not os.path.exists(classifiedPath):
                os.makedirs(classifiedPath)
                print(f"已创建分类文件夹: {classifiedPath}")
                
            self.classifiedFolders[fileExtension] = classifiedPath
    
    def moveFilesToClassifiedFolders(self, filesMap: Dict[str, List[str]]) -> None:
        """
        将文件移动到对应的分类文件夹中
        
        Args:
            filesMap (Dict[str, List[str]]): 文件扩展名映射
        """
        for fileExtension, filesList in filesMap.items():
            targetFolder = self.classifiedFolders[fileExtension]  # 目标文件夹路径
            
            for filePath in filesList:
                fileName = os.path.basename(filePath)  # 获取文件名
                destinationPath = os.path.join(targetFolder, fileName)  # 目标文件路径
                
                try:
                    # 如果目标文件已存在，添加序号
                    if os.path.exists(destinationPath):
                        baseName, extension = os.path.splitext(fileName)  # 分离文件名和扩展名
                        counter = 1  # 计数器
                        while os.path.exists(destinationPath):
                            newFileName = f"{baseName}_{counter}{extension}"  # 新文件名
                            destinationPath = os.path.join(targetFolder, newFileName)
                            counter += 1
                    
                    shutil.move(filePath, destinationPath)
                    print(f"已移动文件: {fileName} -> {os.path.basename(targetFolder)}")
                except Exception as e:
                    print(f"移动文件失败: {fileName}, 错误: {str(e)}")
    
    def classifyFiles(self) -> None:
        """
        执行文件分类的主要方法
        """
        print(f"开始分类 {self.dataPath} 文件夹中的文件...")
        
        # 获取所有文件并按扩展名分组
        filesMap = self.getFilesByExtension()
        
        if not filesMap:
            print("没有找到需要分类的文件")
            return
            
        print(f"找到以下类型的文件: {list(filesMap.keys())}")
        
        # 创建分类文件夹
        self.createClassifiedFolders(filesMap)
        
        # 移动文件到分类文件夹
        self.moveFilesToClassifiedFolders(filesMap)
        
        print("文件分类完成！")
    
    def printClassificationSummary(self) -> None:
        """
        打印分类汇总信息
        """
        print("\n=== 文件分类汇总 ===")
        totalFiles = 0  # 总文件数
        
        for fileExtension, folderPath in self.classifiedFolders.items():
            if os.path.exists(folderPath):
                fileCount = len([f for f in os.listdir(folderPath) if os.path.isfile(os.path.join(folderPath, f))])  # 文件数量
                totalFiles += fileCount
                print(f"{fileExtension} 文件: {fileCount} 个 -> {folderPath}")
            else:
                print(f"{fileExtension} 文件夹不存在: {folderPath}")
                
        print(f"\n总共分类了 {totalFiles} 个文件")

def main():
    """
    主函数，执行文件分类操作
    """
    classifier = FileClassifier()  # 创建文件分类器实例
    classifier.classifyFiles()
    classifier.printClassificationSummary()

if __name__ == "__main__":
    main() 